#include "modalityproperty.h"

#include "../Global/commondefs.h"
#include <QFile>
#include <QApplication>
#include <QDir>

ModalityProperty::ModalityProperty()
{
    readProperty();
}

const ModalityProp *ModalityProperty::getModalityProp(const QString &modality) const
{
    foreach (const ModalityProp *p, props) {
        if (p->name == modality) {
            return p;
        }
    }
    return 0;
}

void ModalityProperty::readProperty()
{
    QFile f(QApplication::applicationDirPath() + QDir::separator() + MODALITY_PROP_XML);
    f.open(QIODevice::ReadOnly);
    xml.setDevice(&f);

    if (xml.readNextStartElement()) {
        if (xml.name() == "modalityProp") {
            while (xml.readNextStartElement()) {
                if (xml.name() == "modalities") {
                    while (xml.readNextStartElement()) {
                        if (xml.name() == "modality") {
                            ModalityProp *m = new ModalityProp;
                            readModality(*m);
                            if (m->name.isEmpty()) delete m;
                            else props << m;

                        } else {
                            xml.skipCurrentElement();
                        }
                    }
                } else {
                    xml.skipCurrentElement();
                }
            }
        } else {
            xml.raiseError(QObject::tr("Invalid modality property xml file."));
        }
    }
}

void ModalityProperty::readModality(ModalityProp &m)
{
    Q_ASSERT(xml.isStartElement() && xml.name() == "modality");

    while (xml.readNextStartElement()) {
        if (xml.name() == "name") {
            m.name = xml.readElementText();
        } else if (xml.name() == "annotation") {
            while (xml.readNextStartElement()) {
                if (xml.name() == "group") {
                    AnnoItemGroup *g = new AnnoItemGroup;
                    readAnnoGroup(*g);
                    if (g->pos.isEmpty()) delete g;
                    else m.groups << g;
                } else {
                    xml.skipCurrentElement();
                }
            }
        } else if (xml.name() == "preference") {
            readPref(m.pref);
        } else {
            xml.skipCurrentElement();
        }
    }
}

void ModalityProperty::readPref(ModalityPref &p)
{
    Q_ASSERT(xml.isStartElement() && xml.name() == "preference");

    double f;
    while (xml.readNextStartElement()) {
        if (xml.name() == "adjust") {
            while (xml.readNextStartElement()) {
                if (xml.name() == "factor") {
                    f = xml.readElementText().toDouble();
                    f = f>0?f:20;
                    p.adjustFactor = f;
                } else {
                    xml.skipCurrentElement();
                }
            }
        } else if (xml.name() == "zoom") {
            while (xml.readNextStartElement()) {
                if (xml.name() == "factor") {
                    f = xml.readElementText().toDouble();
                    f = f>0?f:0.02;
                    p.zoomFactor = f;
                } else if (xml.name() == "max") {
                    f = xml.readElementText().toDouble();
                    f = f>0?f:10;
                    p.zoomMax = f;
                } else if (xml.name() == "min") {
                    f = xml.readElementText().toDouble();
                    f = f>0?f:0.05;
                    p.zoomMin = f;
                } else {
                    xml.skipCurrentElement();
                }
            }
        } else if (xml.name() == "magnifier") {
            while (xml.readNextStartElement()) {
                if (xml.name() == "incremental") {
                    f = xml.readElementText().toDouble();
                    f = f>0?f:1;
                    p.magnifierInc = f;
                } else if (xml.name() == "max") {
                    f = xml.readElementText().toDouble();
                    f = f>0?f:20;
                    p.magnifierMax = f;
                } else if (xml.name() == "min") {
                    f = xml.readElementText().toDouble();
                    f = f>0?f:2;
                    p.magnifierMin = f;
                } else {
                    xml.skipCurrentElement();
                }
            }
        } else {
            xml.skipCurrentElement();
        }
    }
}

void ModalityProperty::readAnnoGroup(AnnoItemGroup &g)
{
    Q_ASSERT(xml.isStartElement() && xml.name() == "group");

    while (xml.readNextStartElement()) {
        if (xml.name() == "position") {
            g.pos = xml.readElementText();
        } else if (xml.name() == "item") {
            AnnoItem *i = new AnnoItem;
            while (xml.readNextStartElement()) {
                if (xml.name() == "text") {
                    i->text = xml.readElementText();
                } else if (xml.name() == "tags") {
                    while (xml.readNextStartElement()) {
                        if (xml.name() == "tag") {
                            DcmTagKey k;
                            while (xml.readNextStartElement()) {
                                if (xml.name() == "group") {
                                    k.setGroup(xml.readElementText().toUShort(0, 0));
                                } else if (xml.name() == "element") {
                                    k.setElement(xml.readElementText().toUShort(0, 0));
                                } else {
                                    xml.skipCurrentElement();
                                }
                            }
                            if (k.hasValidGroup())
                                i->keys << k;
                        } else {
                            xml.skipCurrentElement();
                        }
                    }
                } else {
                    xml.skipCurrentElement();
                }
            }
            if (i->text.isEmpty()) delete i;
            else g.items << i;
        } else {
            xml.skipCurrentElement();
        }
    }
}
